This is a decription of how gcode is currently generated by RepSnapper
(June 2010) I'm write for pedagogical and design purposes.

* Overview By fcrick

Slicing

Slicing is where we cut the original 3d model with a horizontal plane
at a particular height.  The toolpath is the result of processing each
slice of the original model, starting at the bottom, and moving
upwards.  Each layer is separated by the vertical thickness of the
extruded material.  Currently, each slice is processed entirely
independently, and the only information used from the previous slice
when generating the toolpath is just where the extrusion head ended up
at the end of the previous slice.

Models

The model ( is made up of discrete triangles, hopefully all sharing
edges so that they make a full mesh without any holes in it.
Currently, repsnapper (and many 3d programs) use the orientation of a
triangle to determine which side of the triangle represents the inside
of the object we're creating, and which side borders empty space.  So,
for example, if you find the cross product of two edges of a triangle
(say edge 1 cross edge 2), the resulting normal vector will point into
empty space, not into the object.  I'm not sure which way it goes but
it's consistent.  This concept of vertex order dictating orientation
is pretty important and is used throughout the program.

One slice - 3d model to vertices on a plane

When a slice is made at some height, currently we just check every
triangle in the 3d model to see if it intersects that plane.  Usually,
if a triangle intersect ths plane, two of the vectors of the triangle
will have one end above the plane, and one end below - we simple
calculate where those vectors intersect the plane, and those vertices
become part of our output.  Since the two vertices come from the same
triangle, they are linked.  If the plane happens to have the exact
height as one or more of the vertices of the triangle, you can hit a
few edge cases.

Vertex pairs to polygons

The previous step gives us many pairs of vertices - each pair came
from a triangle, but at this point, we just have vertex pairs, when
what we want is the outline of polygons that make up the slice.
Polygons represent either holes or fills, and a hole polygon _should_
exist entirely within a fill polygon. Again, we use the order of the
vertices to designate which are holes and which are fills - one
clockwise, one counter-clockwise.

Currently, we use an algorithm that identifies the vertices closest to
each other, and those vertices are merged.  After a pass of this,
either we have complete polygons or we don't, and if we don't, we
retry the slice at a slightly different height.  It seems like this
algorithm could use some improvement :/

A slice as polygons

At this point, we have polygons that really represent the goal of this
particular layer.  Since the extruder has a thickness, and we can't
just arbitrarily fill in this geometry with a perfect layer of
extrusion material, we can almost never fill in the layer exactly.
Instead, our goal is to generate a path that gives us the best
possible fill that fits this set of polygons best.  Also, typically we
don't bother filling the inside of a model with solid material, since
this just uses more material, and creates a heavier object that isn't
actually any more useful or strong that one with a lot of empty space
inside.

Shrinking - why we shrink the polygons

If we had the extruder just follow the outer edge of our polygon, half
the material would end up outside the polygon, and we'd end up with an
object larger than the model.  To compensate for the width of the
extruded material, we shrink the polygons, so that we end up with
another polygon that is slightly smaller than our target.  If the
extruder follows _that_ polygon, than the outer edge of the extruded
material will match the edge of our original target polygon, and we'll
create an object of the correct size.  This tracing of the outside of
the polygon is called a shell.  If we want multiple shell layers, we
shrink the polygons again, this time by the full thickness of the
extruded material, instead of half, and the extruder can follow that
polygon for an additional shell.

Shrinking - how we shrink

The 'fast' shrinking algorithm basically takes each vertex of the
polygon, and moves it inward.  We use the two adjacent vertices to
decide where the point should be moved.  If the vertex is one pointing
out of the polygon, you need to move the point inward more than that
amount you're shrinking, and you use the angle of the adjoining edges
to find that point.  Also, the 'fill' polygons get shrunk, and the
'hole' polygons get grown.

After all the vertices get moved, we have to reconcile the edges that
have crossed over eachother, and the holes that have grown to overlap
the fill polygons they were inside of before the shrinking.  Right now
we use some external library for this step (gpc polygon something).

There is also a slower, better shrinking algorithm, and Logick is
working on another shrinking algorithm - I don't know how those work.

Infill polygons

After we generate all the shell polygons - the polygons that we intend
to just follow the edge of with the extruder, we create the infill
polygons.  RepSnapper does infill in an extremely simple way.
Basically, we fill the whole plane with parallel lines, and then
extrude along any of the those lines that are within the infill
polygons.  In a particular layer, the lines are always the same
distance apart (the 'infill distance'), and the direction of the lines
changed by a fixed angle between each layer.

Path generation

I haven't really gone through this code yet, but the gist here is we
have to generate a path that includes all the shells, and all the
infills.  There is some logic in there that sorts all these path
segments so that the extruder isn't always traversing large empty gaps
to get from one segment to the next, but I'm not really familiar with
it yet.



* Relating this to the code:

	Much of the code for this flow lives in stl.h / stl.cpp, while
the code moves rapidly, the overall design is fairly constant.

Slicing:
	STL::CalcCuttingPlane
		+ generates a CuttingPlane object as output.
		+ we call 'RegisterPoint' on each new point
			+ this tries to identify unique points.
		+ we AddLine a new 'Segment' which has indexes into these points

